An operating system performs various tasks relating to a computer system, including managing its hardware and software resources. Hardware resources include processors, primary storage (e.g., memory), secondary storage (e.g., hard disk or optical disk), printers, display adapters, network interface cards, input/output ports, etc. Software resources include application programs, user interfaces, device drivers, network protocol stacks, etc. The operating system manages and coordinates these resources to complete various tasks, such as under the direction of an application program.
Operating systems may provide functionality to application programs using subsystems. A subsystem is an operating system component that implements an operating system's application program interfaces (“APIs”). Subsystems may invoke functions of a kernel component. A kernel component is an operating system component that provides core operating system functions.
An operating system may comprise multiple subsystems, each exposing different operating system behaviors. As an example, an operating system may implement a portable operating system interface (“POSIX”) and a MICROSOFT WINDOWS interface as two separate subsystems. These subsystems may both function on a common operating system. Such an operating system may function both with applications designed for POSIX and applications designed for MICROSOFT WINDOWS.
When an application or other software component executes, it may encounter various abnormal conditions. These abnormal conditions may include, e.g., running out of memory, failing to find a file, causing a floating point error of a processor, receiving an illegal instruction, referencing an un-allocated memory page, etc. These abnormal conditions are generally outside the software component's control. When such an abnormal condition is encountered, the operating system may generate an “exception.”
Various software components, including the application program, may have program logic to detect and handle exceptions. As an example, an application may attempt to locate a file when a file cannot be found. As another example, a subsystem may indicate to a user to close applications when memory cannot be allocated to an application requiring additional memory.
Exceptions may also be handled by a debugger. A debugger is a computer program that a software developer may use to debug a software component, e.g., to detect problems in the software component's program logic. As an example, a software developer or system administrator may cause a debugger to automatically attach to a process when an exception is generated by a thread of the process and handle the exception. Handling the exception in a debugger may include suspending execution of the thread in which the exception occurred so that the software developer or system administrator may diagnose the cause of the exception.
An application may use some software components hosted by one subsystem and other software components hosted by another subsystem. Even though an application uses components of both subsystems, the application may operate in a process relating to one of the subsystems. In such a case, exceptions may be provided to the subsystem with which the process is related. As an example, a POSIX application may use component A that is hosted by WINDOWS and component B that is hosted by POSIX. A component is hosted by a subsystem for which the component was built. When the component is built, the component includes an indication of the subsystem for which it is designed. When the component hosted by POSIX causes an exception, the operating system may nevertheless send the exception to the WINDOWS subsystem because the application and the POSIX subsystems may be running as WINDOWS processes. However, the component hosted by POSIX may have program logic designed to handle the exception. Because the operating system is unaware of the program logic, the exception may not be properly handled, and threads and processes of the application may be terminated by the operating system. It would thus be highly desirable to route exceptions between subsystems.